//i2c_ads1115.c
#include "ads1115.h"
#include "usart.h"
#include "stdlib.h"

void ads1115_config_register(IIC_enum IIC_channel,u8 dev,uint8_t pointADD,uint8_t configH,uint8_t configL)
{
    //uint8_t reg_data[3]={pointADD,configH,configL};
    u8 reg_data[2]={0};
    reg_data[0]=configH;
    reg_data[1]=configL;
    // while(HAL_I2C_Master_Transmit(&ads1115_I2cHandle, ADS1115_WRITE_ADDRESS, reg_data, 3, 1000) != HAL_OK)
    // {
    //     if(HAL_I2C_GetError(&ads1115_I2cHandle) != HAL_I2C_ERROR_AF)
    //     {
    //         printf("ads1115 Config Register error!!!\r\n");
    //     }
    // }
   // u8 IICwriteBytes(IIC_enum IIC_channel,u8 dev, u8 reg, u8 length, u8* data){
    //向控制寄存器写
    IICwriteBytes(IIC_channel,dev, ADS1015_REG_POINTER_CONFIG, 2,reg_data);
    // printf("set dev: %#x  reg:%#X  %#X %#X\r\n",ADS1015_REG_POINTER_CONFIG ,dev,reg_data[0],reg_data[1]);
    // IICwriteBytes(IIC_channel,dev, ADS1015_REG_POINTER_LOWTHRESH, 2,reg_data);
    // printf("set dev: %#x  reg:%#X  %#X %#X\r\n",ADS1015_REG_POINTER_LOWTHRESH ,dev,reg_data[0],reg_data[1]);
    // IICwriteBytes(IIC_channel,dev, ADS1015_REG_POINTER_HITHRESH, 2,reg_data);
    // printf("set dev: %#x  reg:%#X  %#X %#X\r\n",ADS1015_REG_POINTER_HITHRESH ,dev,reg_data[0],reg_data[1]);
}
int16_t ads1115_read_data(IIC_enum IIC_channel,u8 dev)
{
    int16_t data;
    u8 rx_data[2]={0};

    // while(HAL_I2C_Master_Transmit(&ads1115_I2cHandle, ADS1115_WRITE_ADDRESS, 0x00, 1, 1000) != HAL_OK)
    // {
    //     if(HAL_I2C_GetError(&ads1115_I2cHandle) != HAL_I2C_ERROR_AF)
    //     {
    //         printf("ads1115 convert Register error!!!\r\n");
    //     }
    // }
    //IICwriteBytes(IIC_channel,dev,ADS1015_REG_POINTER_CONVERT,1,0x00);//dev
    // while(HAL_I2C_Master_Receive(&ads1115_I2cHandle, ADS1115_READ_ADDRESS, rx_data, 2, 1000) != HAL_OK)
    // {
    //     if(HAL_I2C_GetError(&ads1115_I2cHandle) != HAL_I2C_ERROR_AF)
    //     {
    //         printf("ads1115 read data error!!!\r\n");
    //     }
    // }
    /*
    IICreadBytes(IIC_channel,dev, 0x01, 2,rx_data);
    printf("read  %#X  back:%#X %#X\r\n",0x01,rx_data[0],rx_data[1]);
    IICreadBytes(IIC_channel,dev, 0x02, 2,rx_data);
    printf("read  %#X  back:%#X %#X\r\n",0x02,rx_data[0],rx_data[1]);
    IICreadBytes(IIC_channel,dev, 0x03, 2,rx_data);
    printf("read  %#X  back:%#X %#X\r\n",0x03,rx_data[0],rx_data[1]);
    //IIC_Send_Byte(IIC0,0);
    //rx_data[0]=IIC_Read_Byte(IIC0,0);
    //rx_data[1]=IIC_Read_Byte(IIC0,0);
    //data = ((rx_data[0] << 8) & 0xFF00) | rx_data[1];
    */
//     IICreadBytes(IIC_channel,dev, ADS1015_REG_POINTER_LOWTHRESH, 2,rx_data);
//     printf(">>>read Raw:%#X,%#X, data:%d  %#X\r\n",rx_data[0],rx_data[1],data,data);
//    IICreadBytes(IIC_channel,dev, ADS1015_REG_POINTER_HITHRESH, 2,rx_data);
//     printf(">>>read Raw:%#X,%#X, data:%d  %#X\r\n",rx_data[0],rx_data[1],data,data);

    //IICreadBytes(IIC_channel,dev, ADS1015_REG_POINTER_CONFIG, 2,rx_data);
    // while(rx_data[0]&0x80==0)
    // {
    //     IICreadBytes(IIC_channel,dev, ADS1015_REG_POINTER_CONFIG, 2,rx_data);
    //     printf("---read Raw:%#X,%#X, data:%d  %#X\r\n",rx_data[0],rx_data[1],data,data);
    //     printf("wait...\r\n");
    // }
    
    IICreadBytes(IIC_channel,dev, ADS1015_REG_POINTER_CONVERT, 2,rx_data);
    data=rx_data[0]*256+rx_data[1];
    // printf(">>>read Raw:%#X,%#X, data:%d  %#X\r\n",rx_data[0],rx_data[1],data,data);
    //printf("(u16)rx_data[0]<<8:%d,%#X \r\n",((u16)rx_data[0])<<8+(u16)rx_data[1],((u16)rx_data[0])<<8+(u16)rx_data[1]);
    return data;
}

void ads1115_get_voltage_val(IIC_enum IIC_channel,u8 dev,uint8_t configH,uint8_t configL,u16* raw,double* result)
{
    double val;
    int16_t ad_val;
    
    ads1115_config_register(IIC_channel,dev,ADS1015_REG_POINTER_CONFIG,configH,configL);
    delay_ms(10);
    ad_val=ads1115_read_data(IIC_channel,dev);
    *raw=ad_val;
    //printf("1115read:%d  %#X\r\n",ad_val,ad_val);
    if((ad_val==0x7FFF)|(ad_val==0X8000))//是否超量程了
    {
        ad_val=0;
        printf("over PGA\r\n");
    }
    switch((0x0E&configH)>>1)//量程对应的分辨率
    {
        case(0x00):
            val=(double)ad_val*187.5/1000000.0;//
        break;
        case(0x01):
            val=(double)ad_val*125/1000000.0;
        break;
        case(0x02):
            val=(double)ad_val*62.5/1000000.0;
        break;
        case(0x03):
            val=(double)ad_val*31.25/1000000.0;
        break;
        case(0x04):
            val=(double)ad_val*15.625/1000000.0;
        break;
        case(0x05):
            val=(double)ad_val*7.8125/1000000.0;
        break;
    }
    *result= val;
}
void ads1015_get_voltage_val(IIC_enum IIC_channel,u8 dev,uint8_t configH,uint8_t configL,u16* raw,double* result)
{
    double val;
    int16_t ad_val;
    
    ads1115_config_register(IIC_channel,dev,0x01,configH,configL);
    //delay_ms(10);
    ad_val=ads1115_read_data(IIC_channel,dev);
    
    if((ad_val==0x7FF0)|(ad_val==0X8000))//是否超量程了
    {
        ad_val=0;
        printf("  x x    over PGA\r\n");
    }
    //在这里的溢出处理方式并不合理，测量过程中会出现边界值
    //必须重新测量，重新获取，但是重新获取的两次都有可能出现量程错误，需要使用
    //全量程或大一级别的量程
    //ad_val=(uint16_t)ad_val>>4;
    *raw=ad_val;
    //printf("read:%d  %#X\r\n",ad_val,ad_val);
        switch((0x0E&configH)>>1)//量程对应的分辨率
    {
        case(0x00):
            val=(double)ad_val*187.5/1000000.0;//
        break;
        case(0x01):
            val=(double)ad_val*125/1000000.0;
        break;
        case(0x02):
            val=(double)ad_val*62.5/1000000.0;
        break;
        case(0x03):
            val=(double)ad_val*31.25/1000000.0;
        break;
        case(0x04):
            val=(double)ad_val*15.625/1000000.0;
        break;
        case(0x05):
            val=(double)ad_val*7.8125/1000000.0;
        break;
    }
    *result= val;
}
void ads1115_init(IIC_enum IIC_channel,u8 dev)
{
    //config 
    //u8 reg_data[2]={0xf0,0x62};
    u8 reg_data[2]={CONFIG_REG_H,CONFIG_REG_L};
    //比较器功能的阈值设定，这里不使用比较器，故不配置
	// u16 L_TH=1000,H_TH=30000;
    IICwriteBytes(IIC_channel,dev, ADS1015_REG_POINTER_CONFIG, 2,reg_data);

    //set low
   
    // reg_data[0]=L_TH>>8;
    // reg_data[1]=L_TH;
    //IICwriteBytes(IIC_channel,ADS1115_WRITE_ADDRESS, ADS1015_REG_POINTER_LOWTHRESH, 2,reg_data);
    // reg_data[0]=H_TH>>8;
    // reg_data[1]=H_TH;
    //IICwriteBytes(IIC_channel,ADS1115_WRITE_ADDRESS, ADS1015_REG_POINTER_HITHRESH, 2,reg_data);
}


void get_ads_data(IIC_enum IIC_channel,u8 dev,u8 channel,u16 pga,u16* raw,double* result)
{
    uint8_t channel_cmd,pga_cmd;
    uint8_t cmd_h;
    uint8_t cmd_l;
    switch(channel){
        case 0:{
            channel_cmd=ADS1115_REG_CONFIG_MUX_SINGLE_0;
        }break;
        case 1:{
            channel_cmd=ADS1115_REG_CONFIG_MUX_SINGLE_1;
        }break;
        case 2:{
            channel_cmd=ADS1115_REG_CONFIG_MUX_SINGLE_2;
        }break;
        case 3:{
             channel_cmd=ADS1115_REG_CONFIG_MUX_SINGLE_3;
        }break;
    default :print("channel fault\r\n");break;
    }
    // printf("channel %d\r\n",channel);
    switch(pga){
        case 61144:{
            pga_cmd=ADS1115_REG_CONFIG_PGA_6_1144;
        }break;
        case 4096:{
            pga_cmd=ADS1115_REG_CONFIG_PGA_4_096;
        }break;
        case 2048:{
             pga_cmd=ADS1115_REG_CONFIG_PGA_2_048;

        }break;
        case 1024:{
             pga_cmd=ADS1115_REG_CONFIG_PGA_1_024;

        }break;
        case 512:{
             pga_cmd=ADS1115_REG_CONFIG_PGA_0_512;

        }break;
        case 256:{
             pga_cmd=ADS1115_REG_CONFIG_PGA_0_256;
        }break;
    default :print("PGA fault\r\n");break;
    }
    // printf("pga %d\r\n",pga);
    cmd_h=ADS1115_REG_CONFIG_OS_START|\
        channel_cmd|\
        pga_cmd|\
        ADS1115_REG_CONFIG_MODE_SINGLE;
    cmd_l=ADS1115_REG_CONFIG_DR_128|\
            ADS1115_REG_CONFIG_COMP_MODE_TRADITIONAL|\
            ADS1115_REG_CONFIG_COMP_POL_LOW|\
            ADS1115_REG_CONFIG_COMP_LAT_NONLATCH|\
            ADS1115_REG_CONFIG_COMP_QUE_DIS;
        //cmd_h=0x85;
        //cmd_l=0x83;
#if   USE_ADS_Type ==ADS1015
    ads1015_get_voltage_val(IIC_channel,dev,cmd_h,cmd_l,raw,result);
#elif USE_ADS_Type ==ADS1115
    ads1115_get_voltage_val(IIC_channel,dev,cmd_h,cmd_l,raw,result);
#endif
}
/************************
 * 最佳量程选择  OPT操作
 * 第一次使用全量程，再重确定最佳量程
 * 获取最高精确度
 * *********************/
//这种处理方法不够可靠，换成举手表决
//若测量值处于安全区间，可以使用同一个等级进行连续测量提高精度、增强抗噪声能力
void ADS_auto_pga(IIC_enum IIC_channel,u8 dev,u8 channel,u16 *pga_level,u16* raw,double* result)
{
    get_ads_data(IIC_channel,dev,channel,61144,raw,result);//第一次全量程测量
    if(*result>4.096)// 量程选择状态机
    {
       *pga_level=61144;
       return;
    }
    else if(*result>2.048)
    {
        *pga_level=4096;
        get_ads_data(IIC_channel,dev,channel,*pga_level,raw,result);
        return;
    }
    else if(*result>1.024)
    {
        *pga_level=2048;
        get_ads_data(IIC_channel,dev,channel,*pga_level,raw,result);
        return;
    }
    else if(*result>0.512)
    {
        *pga_level=1024;
        get_ads_data(IIC_channel,dev,channel,*pga_level,raw,result);
        return;
    }
    else if(*result>0.256)
    {
        *pga_level=512;
        get_ads_data(IIC_channel,dev,channel,*pga_level,raw,result);
        return;
    }
    else
    {
        *pga_level=256;
        get_ads_data(IIC_channel,dev,channel,*pga_level,raw,result);
        return;
    }
}





